package com.maixy.studyonlineapi.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.maixy.studyonlineapi.constants.GlobalConstant;
import com.maixy.studyonlineapi.entity.BaseModel;
import com.maixy.studyonlineapi.redis.template.ValueRedisTemplate;
import com.maixy.studyonlineapi.utils.RedisKeyUtil;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;

/**
 * @Classname BaseMPlusService
 * @Description TODO
 * @Date 2020/11/1 17:12
 * @Author by maixy
 */
public class BaseMPlusService<T extends BaseModel, ID extends Serializable> {
    private final BaseMapper<T> baseMapper;

    private Class<T> entityClass;

    @Resource
    private ValueRedisTemplate valueRedisTemplate;

    protected BaseMPlusService(Class<T> entityClass, BaseMapper<T> baseMapper) {
        this.entityClass = entityClass;
        this.baseMapper = baseMapper;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public T create(T entity) {
        if (entity.getCreateTime() == null || entity.getCreateTime() == -1L) {
            entity.setCreateTime(System.currentTimeMillis());
        }
        if (baseMapper.insert(entity) > 0) {
            return entity;
        } else {
            return null;
        }
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public T update(T entity) {
        if (entity.getUpdateTime() == null || entity.getUpdateTime() == -1L) {
            entity.setUpdateTime(System.currentTimeMillis());
        }
        if (baseMapper.updateById(entity) > 0) {
            valueRedisTemplate.del(RedisKeyUtil.build(entityClass.getName(), String.valueOf(entity.getId())));
            return entity;
        } else {
            return null;
        }
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void delete(Long id) {

        baseMapper.deleteById(id);

        valueRedisTemplate.del(RedisKeyUtil.build(entityClass.getName(), String.valueOf(id)));
    }

//    public T findById(Long id) {
//        if (id == null) {
//            return null;
//        }
//        return baseMapper.selectById(id);
//    }
    public T findById(ID id) {

        String key = RedisKeyUtil.build(entityClass.getName(), id);
        T entity;
        if (valueRedisTemplate.exists(key)) {
            String json = valueRedisTemplate.get(key);
            entity = JSON.parseObject(json, entityClass);
        } else {
            entity = baseMapper.selectById(id);

            if (null != entity) {
                valueRedisTemplate.set(key, JSON.toJSONString(entity), GlobalConstant.Times.ONE_DAY);
            }
        }
        return entity;
    }
}
